package com.witmore.neutron.ai.mcp.server.trading.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.witmore.neutron.ai.mcp.server.trading.db.entity.ScorpionStockAbnormalRecordDO;
import com.witmore.neutron.ai.mcp.server.trading.db.mapper.ScorpionStockAbnormalRecordMapper;
import com.witmore.neutron.ai.mcp.server.trading.dto.ScorpionStockAbnormalRecordDTO;
import com.witmore.neutron.ai.mcp.server.trading.dto.StockAbnormalRecordResponse;
import com.witmore.neutron.ai.mcp.server.trading.service.StockAbnormalRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 股票异动记录服务实现类
 */
@Slf4j
@Service
public class StockAbnormalRecordServiceImpl implements StockAbnormalRecordService {

    @Autowired
    private ScorpionStockAbnormalRecordMapper abnormalRecordMapper;

    @Override
    public Page<StockAbnormalRecordResponse> queryAbnormalRecords(Long userId, String stockCode, String stockName,
                                                                Integer abnormalTypeCode, LocalDate startDate, LocalDate endDate,
                                                                long page, long size) {
        try {
            LambdaQueryWrapper<ScorpionStockAbnormalRecordDO> queryWrapper = new LambdaQueryWrapper<ScorpionStockAbnormalRecordDO>()
                    .eq(ScorpionStockAbnormalRecordDO::getUserId, userId)
                    .eq(ScorpionStockAbnormalRecordDO::getIsDeleted, 0)
                    .like(StringUtils.hasText(stockCode) ,ScorpionStockAbnormalRecordDO::getStockCode, stockCode)
                    .like(StringUtils.hasText(stockName) ,ScorpionStockAbnormalRecordDO::getStockName, stockName)
                    // 确保 fallRatio 和 riseRatio 不能同时为 NULL
                    .and(wrapper -> wrapper
                            .isNotNull(ScorpionStockAbnormalRecordDO::getFallRatio)
                            .or()
                            .isNotNull(ScorpionStockAbnormalRecordDO::getRiseRatio)
                    )
                    // 上涨和下跌幅度都不能为空
                    .orderByDesc(ScorpionStockAbnormalRecordDO::getCreateTime);

            // 日期范围查询
            if (startDate != null) {
                LocalDateTime startDateTime = startDate.atStartOfDay();
                queryWrapper.ge(ScorpionStockAbnormalRecordDO::getCreateTime, startDateTime);
            }
            if (endDate != null) {
                LocalDateTime endDateTime = endDate.atTime(LocalTime.MAX);
                queryWrapper.le(ScorpionStockAbnormalRecordDO::getCreateTime, endDateTime);
            }
            // 异动类型过滤
            if (abnormalTypeCode != null) {
                if (abnormalTypeCode == 1) {
                    // 涨幅异动
                    queryWrapper.gt(ScorpionStockAbnormalRecordDO::getRiseRatio, BigDecimal.ZERO);
                } else if (abnormalTypeCode == 2) {
                    // 跌幅异动
                    queryWrapper.gt(ScorpionStockAbnormalRecordDO::getFallRatio, BigDecimal.ZERO);
                } else if (abnormalTypeCode == 0) {
                    // 涨幅为null 跌幅为 null
                    queryWrapper.isNull(ScorpionStockAbnormalRecordDO::getRiseRatio);
                    queryWrapper.isNull(ScorpionStockAbnormalRecordDO::getFallRatio);
                }
            }

            Page<ScorpionStockAbnormalRecordDO> resultPage = abnormalRecordMapper.selectPage(new Page<>(page, size), queryWrapper);

            // 转换结果
            Page<StockAbnormalRecordResponse> responsePage = new Page<>();
            BeanUtils.copyProperties(resultPage, responsePage, "records");

            List<StockAbnormalRecordResponse> responseList = resultPage.getRecords().stream()
                    .map(this::convertToResponse)
                    .collect(Collectors.toList());
            responsePage.setRecords(responseList);

            log.info("分页查询异动记录成功: userId={}, total={}", userId, responsePage.getTotal());
            return responsePage;
        } catch (Exception e) {
            log.error("分页查询异动记录失败: userId={}", userId, e);
            return new Page<>();
        }
    }

    @Override
    public StockAbnormalRecordResponse getAbnormalRecordById(Long recordId) {
        try {
            ScorpionStockAbnormalRecordDO recordDO = abnormalRecordMapper.selectById(recordId);
            if (recordDO == null || recordDO.getIsDeleted() == 1) {
                log.warn("异动记录不存在: recordId={}", recordId);
                return null;
            }

            StockAbnormalRecordResponse response = convertToResponse(recordDO);
            log.info("获取异动记录详情成功: recordId={}", recordId);
            return response;
        } catch (Exception e) {
            log.error("获取异动记录详情失败: recordId={}", recordId, e);
            return null;
        }
    }

    @Override
    public List<ScorpionStockAbnormalRecordDTO> queryAbnormalRecordsList(Long userId, String stockCode,
                                                                        String startTime, String endTime, Integer limit) {
        try {
            // 设置默认值和限制
            if (limit == null || limit <= 0) {
                limit = 10;
            }
            if (limit > 100) {
                limit = 100;
            }

            log.info("开始查询用户异动记录列表 - 用户ID: {}, 股票代码: {}, 限制条数: {}", userId, stockCode, limit);

            // 构建查询条件
            LambdaQueryWrapper<ScorpionStockAbnormalRecordDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ScorpionStockAbnormalRecordDO::getUserId, userId)
                    .eq(ScorpionStockAbnormalRecordDO::getIsDeleted, (byte) 0);

            // 时间范围查询（字符串格式）
            if (StringUtils.hasText(startTime)) {
                try {
                    LocalDateTime startDateTime = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    queryWrapper.ge(ScorpionStockAbnormalRecordDO::getCreateTime, startDateTime);
                } catch (Exception e) {
                    log.warn("解析开始时间失败: {}", startTime, e);
                }
            }
            if (StringUtils.hasText(endTime)) {
                try {
                    LocalDateTime endDateTime = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    queryWrapper.le(ScorpionStockAbnormalRecordDO::getCreateTime, endDateTime);
                } catch (Exception e) {
                    log.warn("解析结束时间失败: {}", endTime, e);
                }
            }

            // 如果指定了股票代码，则按股票代码筛选
            if (StringUtils.hasText(stockCode)) {
                queryWrapper.eq(ScorpionStockAbnormalRecordDO::getStockCode, stockCode.trim());
            }

            // 按创建时间倒序排列，并限制返回条数
            queryWrapper.orderByDesc(ScorpionStockAbnormalRecordDO::getCreateTime)
                    .last("LIMIT " + limit);

            List<ScorpionStockAbnormalRecordDO> records = abnormalRecordMapper.selectList(queryWrapper);

            log.info("查询异动记录列表完成 - 用户ID: {}, 股票代码: {}, 返回条数: {}", userId, stockCode, records.size());
            return records.stream().map(record -> {
                ScorpionStockAbnormalRecordDTO dto = new ScorpionStockAbnormalRecordDTO();
                BeanUtils.copyProperties(record, dto);
                return dto;
            }).collect(Collectors.toList());

        } catch (Exception e) {
            log.error("查询股票异动记录列表失败 - 用户ID: {}, 股票代码: {}", userId, stockCode, e);
            return new java.util.ArrayList<>();
        }
    }

    @Override
    public Object getAlertDetail(Integer alertId) {
        try {
            ScorpionStockAbnormalRecordDO recordDO = abnormalRecordMapper.selectById(alertId.longValue());
            if (recordDO == null || recordDO.getIsDeleted() == 1) {
                log.warn("异动预警记录不存在: alertId={}", alertId);
                return null;
            }

            Map<String, Object> result = new HashMap<>();

            // 解析异动数据
            String abnormalData = recordDO.getAbnormalData();
            if (StringUtils.hasText(abnormalData)) {
                try {
                    Map<String, Object> dataMap = JSONObject.parseObject(abnormalData, Map.class);
                    result.putAll(dataMap);
                } catch (Exception e) {
                    log.error("解析异动数据失败: alertId={}, abnormalData={}", alertId, abnormalData, e);
                }
            }

            // 添加基本信息
            result.put("stockName", recordDO.getStockName());
            result.put("stockCode", recordDO.getStockCode());
            result.put("riseRatio", recordDO.getRiseRatio());
            result.put("fallRatio", recordDO.getFallRatio());
            result.put("abnormalReportAttachmentUrl", recordDO.getAbnormalReportAttachmentUrl());
            result.put("createTime", recordDO.getCreateTime());

            log.info("获取异动预警详情成功: alertId={}", alertId);
            return result;
        } catch (Exception e) {
            log.error("获取异动预警详情失败: alertId={}", alertId, e);
            return null;
        }
    }

    /**
     * 将DO对象转换为Response对象
     */
    private StockAbnormalRecordResponse convertToResponse(ScorpionStockAbnormalRecordDO recordDO) {
        StockAbnormalRecordResponse response = new StockAbnormalRecordResponse();
        BeanUtils.copyProperties(recordDO, response);

        // 从abnormalData JSON中解析额外字段
        if (StringUtils.hasText(recordDO.getAbnormalData())) {
            try {
                JSONObject abnormalJson = JSONObject.parseObject(recordDO.getAbnormalData());

                // 解析当前价格
                if (abnormalJson.containsKey("currentPrice")) {
                    response.setCurrentPrice(abnormalJson.getBigDecimal("currentPrice"));
                }

                // 解析昨日收盘价
                if (abnormalJson.containsKey("yesterdayClosePrice")) {
                    response.setYesterdayClosePrice(abnormalJson.getBigDecimal("yesterdayClosePrice"));
                }
                // 涨跌幅度
                if (abnormalJson.containsKey("changeRatio")) {
                    response.setAbnormalRatio(abnormalJson.getBigDecimal("changeRatio"));
                }
                // 涨跌状态
                if (abnormalJson.containsKey("abnormalType")) {
                    response.setAbnormalType(abnormalJson.getString("abnormalType"));
                }
                // 涨跌类型
                if (abnormalJson.containsKey("abnormalTypeCode")) {
                    response.setAbnormalTypeCode(abnormalJson.getInteger("abnormalTypeCode"));
                }
                // 如果没有昨日收盘价但有lastPrice，使用lastPrice
                if (response.getYesterdayClosePrice() == null && abnormalJson.containsKey("lastPrice")) {
                    response.setYesterdayClosePrice(abnormalJson.getBigDecimal("lastPrice"));
                }
                if (abnormalJson.containsKey("triggerThreshold")) {
                    response.setTriggerThreshold(abnormalJson.getBigDecimal("triggerThreshold"));
                }
                if (abnormalJson.containsKey("triggerTime")) {
                    response.setTriggerTime(abnormalJson.getString("triggerTime"));
                }

                log.debug("解析异动数据成功: recordId={}, currentPrice={}, yesterdayClosePrice={}",
                    recordDO.getId(), response.getCurrentPrice(), response.getYesterdayClosePrice());

            } catch (Exception e) {
                log.warn("解析异动数据失败: recordId={}, abnormalData={}", recordDO.getId(), recordDO.getAbnormalData(), e);
            }
        }

        return response;
    }
}
